<?php

/**
 * This is the model class for table "prefix_topic".
 *
 * The followings are the available columns in table 'prefix_topic':
 * @property string $topic_id
 * @property string $blog_id
 * @property string $user_id
 * @property string $topic_type
 * @property string $topic_title
 * @property string $topic_tags
 * @property string $topic_date_add
 * @property string $topic_date_edit
 * @property string $topic_user_ip
 * @property integer $topic_publish
 * @property integer $topic_publish_draft
 * @property integer $topic_publish_index
 * @property double $topic_rating
 * @property string $topic_count_vote
 * @property string $topic_count_read
 * @property string $topic_count_comment
 * @property string $topic_cut_text
 * @property integer $topic_forbid_comment
 * @property string $topic_text_hash
 * @property Blog $blog
 * @property User $user
 * @property TopicContent $topicContent
 * @property array(User) $readUsers
 * @property array(TopicTag) $topicTags
 */
class Topic extends LsActiveRecord
{
	/**
	 * Returns the static model of the specified AR class.
	 * @return Topic the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return Config::Get('db.table.topic');
	}
	
	public function getEntity(){
		if($entity = parent::getEntity()){
			
			if($this->hasRelated('topicContent')
			&& $content = $this->getRelated('topicContent')){
				$entity->_setData($content->getAttributes());
			}
			
			if($this->hasRelated('userTopicRead')
			&& $topicRead = $this->getRelated('userTopicRead')){
				$entity->setDateRead($topicRead->date_read);
				$entity->setCountCommentNew(
					$entity->getCountComment() - $topicRead->comment_count_last
				);
			}
			
			if($this->hasRelated('userFavourite')
			&& $favourite = $this->getRelated('userFavourite')){
				$entity->setIsFavourite((bool) $favourite);
			}
			
			if($this->hasRelated('userQuestionVote')
			&& $questionVote = $this->getRelated('userQuestionVote')){
				$entity->setUserQuestionIsVote((bool) $questionVote);
			}
			
			return $entity;
		}
	}
	
	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			array('blog_id, user_id, topic_title, topic_tags, topic_date_add, topic_user_ip, topic_text_hash', 'required'),
			array('topic_publish, topic_publish_draft, topic_publish_index, topic_forbid_comment', 'numerical', 'integerOnly'=>true),
			array('topic_rating', 'numerical'),
			array('blog_id, user_id, topic_count_vote, topic_count_read, topic_count_comment', 'length', 'max'=>11),
			array('topic_type', 'length', 'max'=>8),
			array('topic_title', 'length', 'max'=>200),
			array('topic_tags', 'length', 'max'=>250),
			array('topic_user_ip', 'length', 'max'=>20),
			array('topic_cut_text', 'length', 'max'=>100),
			array('topic_text_hash', 'length', 'max'=>32),
			array('topic_date_edit', 'safe'),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			array('topic_id, blog_id, user_id, topic_type, topic_title, topic_tags, topic_date_add, topic_date_edit, topic_user_ip, topic_publish, topic_publish_draft, topic_publish_index, topic_rating, topic_count_vote, topic_count_read, topic_count_comment, topic_cut_text, topic_forbid_comment, topic_text_hash', 'safe', 'on'=>'search'),
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'blog' => array(self::BELONGS_TO, 'Blog', 'blog_id'),
			'user' => array(self::BELONGS_TO, 'User', 'user_id'),
			'topicContent' => array(self::HAS_ONE, 'TopicContent', 'topic_id'),
			'readUsers' => array(self::MANY_MANY, 'User', Config::Get('db.table.topic_read').'(topic_id, user_id)'),
			'userTopicRead' => array(
				self::HAS_ONE,
				'TopicRead',
				'topic_id',
				'on' => '{%child}.user_id='.(User::me()?User::me()->user_id:0),
			),
			'userFavourite' => array(
				self::HAS_ONE,
				'Favourite',
				'target_id',
				'on' => '{%child}.target_type="topic"'
					.' and {%child}.user_id='.(User::me()?User::me()->user_id:0),
			),
			'topicTags' => array(
				self::HAS_MANY,
				'TopicTag',
				'topic_id',
			),
			'countComments' => array(
				self::STAT,
				'Comment',
				'target_parent_id',
				'condition' => '{%child}.target_type="topic"',
			),
			'comments' => array(
				self::HAS_MANY,
				'Comment',
				'target_parent_id',
				'condition' => '{%child}.target_type="topic"',
			),
			'countFavourites' => array(
				self::STAT,
				'Favourite',
				'target_id',
				'condition' => '{%child}.target_type="topic"',
			),
			'favourites' => array(
				self::HAS_MANY,
				'Favourite',
				'target_id',
				'condition' => '{%child}.target_type="topic"',
			),
			'countVotes' => array(
				self::STAT,
				'Vote',
				'target_id',
				'condition' => '{%child}.target_type="topic"',
			),
			'votes' => array(
				self::HAS_MANY,
				'Vote',
				'target_id',
				'condition' => '{%child}.target_type="topic"',
			),
			'vote' => array(
				self::HAS_ONE,
				'Vote',
				'target_id',
				'condition' => '',
				'on' => '{%child}.target_type="topic"'
					.' and {%child}.user_voter_id='.(User::me()?User::me()->user_id:0),
			),
			'votesPlus' => array(
				self::HAS_MANY,
				'Vote',
				'target_id',
				'condition' => '{%child}.target_type="topic" and {%child}.vote_direction=1',
			),
			'votesMinus' => array(
				self::HAS_MANY,
				'Vote',
				'target_id',
				'condition' => '{%child}.target_type="topic" and {%child}.vote_direction=-1',
			),
			'countVotesPlus' => array(
				self::STAT,
				'Vote',
				'target_id',
				'condition' => '{%child}.target_type="topic" and {%child}.vote_direction=1',
			),
			'countVotesMinus' => array(
				self::STAT,
				'Vote',
				'target_id',
				'condition' => '{%child}.target_type="topic" and {%child}.vote_direction=-1',
			),
			'userQuestionVote' => array(
				self::HAS_ONE,
				'TopicQuestionVote',
				'topic_id',
				'on' => '{%child}.user_voter_id='.(User::me()?User::me()->user_id:0),
			),
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'topic_id' => 'Topic',
			'blog_id' => 'Blog',
			'user_id' => 'User',
			'topic_type' => 'Topic Type',
			'topic_title' => 'Topic Title',
			'topic_tags' => 'Topic Tags',
			'topic_date_add' => 'Topic Date Add',
			'topic_date_edit' => 'Topic Date Edit',
			'topic_user_ip' => 'Topic User Ip',
			'topic_publish' => 'Topic Publish',
			'topic_publish_draft' => 'Topic Publish Draft',
			'topic_publish_index' => 'Topic Publish Index',
			'topic_rating' => 'Topic Rating',
			'topic_count_vote' => 'Topic Count Vote',
			'topic_count_read' => 'Topic Count Read',
			'topic_count_comment' => 'Topic Count Comment',
			'topic_cut_text' => 'Topic Cut Text',
			'topic_forbid_comment' => 'Topic Forbid Comment',
			'topic_text_hash' => 'Topic Text Hash',
		);
	}
	
	
	public function getTitleSafe(){
		return htmlspecialchars($this->topic_title);
	}
	
	
	public function getLink($htmlOptions=array()){
		return CHtml::link($this->getTitleSafe(), $this->getEntity()->getUrl(), $htmlOptions);
	}
	
	
	public function getIsNew(){
		return strtotime($this->topic_date_add) >= (time()-Config::Get('module.topic.new_time'));
	}
	
	public function recent($limit=5){
		$this->getDbCriteria()->mergeWith(array(
			'order' => '{%this}.topic_date_add desc',
			'limit' => $limit,
		));
		return $this;
	}
	
	public function lastByTime($time=86400){
		if(preg_match('#^(\d+)([hdmy])$#', $time, $match)){
			if($match[2]=='h'){
				$time = $match[1]*3600;
			}elseif($match[2]=='d'){
				$time = $match[1]*3600*24;
			}elseif($match[2]=='m'){
				$time = $match[1]*2629744;
			}elseif($match[2]=='y'){
				$time = $match[1]*31556926;
			}
		}
		$this->getDbCriteria()->mergeWith(array(
			'condition' => '{%this}.topic_date_add>="'
				.date("Y-m-d H:00:00",time()-$time).'"'
		));
		return $this;
	}
	
	public function byTag($tag){
		$this->getDbCriteria()->mergeWith(array(
			'condition' => '{%this}.topic_id in (select topic_id from '
				.TopicTag::model()->tableName().' where topic_tag_text=:tag)',
			'params' => array(':tag' => $tag),
		));
		return $this;
	}
	
	public function scopes(){
		return array(
			'index' => array(
				'condition' => '{%this}.topic_rating>='.strtr(Config::Get('module.blog.index_good'),',','.')
					.' or {%this}.topic_publish_index=1',
				'alias' => $this->tableName(),
			),
			'personal' => array(
				'condition' => '{%this}.blog_id in(select blog_id from '
					.Blog::model()->tableName().' where blog_type="personal")',
				'alias' => $this->tableName(),
			),
			'collective' => array(
				'condition' => '{%this}.blog_id in(select blog_id from '
					.Blog::model()->tableName().' where blog_type!="personal")',
				'alias' => $this->tableName(),
			),
			'publish' => array(
				'condition' => '{%this}.topic_publish=1',
				'alias' => $this->tableName(),
			),
			'new' => array(
				'condition' => '{%this}.topic_date_add>="'
					.date("Y-m-d H:00:00",time()-Config::Get('module.topic.new_time')).'"',
				'alias' => $this->tableName(),
			),
			'collectiveGood' => array(
				'condition' => '{%this}.topic_rating>='.strtr(Config::Get('module.blog.collective_good'),',','.'),
				'alias' => $this->tableName(),
			),
			'collectiveBad' => array(
				'condition' => '{%this}.topic_rating<'.strtr(Config::Get('module.blog.collective_good'),',','.'),
				'alias' => $this->tableName(),
			),
			'personalGood' => array(
				'condition' => '{%this}.topic_rating>='.strtr(Config::Get('module.blog.personal_good'),',','.'),
				'alias' => $this->tableName(),
			),
			'personalBad' => array(
				'condition' => '{%this}.topic_rating<'.strtr(Config::Get('module.blog.personal_good'),',','.'),
				'alias' => $this->tableName(),
			),
		);
	}
}